#include <stdio.h>
#include "pico/stdlib.h"
#include "pico/binary_info.h"
#include "hardware/spi.h"

#include "wizchip_conf.h"
#include "w5500.h"
#include "w5500_spi.h"
#include "dhcp.h"

#define ETHERNET_BUF_MAX_SIZE (1024 * 2)
#define SOCKET_DHCP 0
#define DHCP_RETRY_COUNT 5

wiz_NetInfo net_info = {
    .mac = {0x00, 0x08, 0xdc, 0x16, 0xed, 0x2e},
    .ip = {192, 168, 1, 120},
    .sn = {255, 255, 255, 0},
    .gw = {192, 168, 1, 1},
    .dns = {8, 8, 8, 8},
    .dhcp = NETINFO_DHCP};
static uint8_t dhcp_get_ip_flag = 0;
static uint8_t ethernet_buf[ETHERNET_BUF_MAX_SIZE] = {
    0,
};
uint8_t retval = 0;
uint8_t dhcp_retry = 0;

static void dhcp_init(void);
static void dhcp_conflict(void);
static void dhcp_assign(void);
bool repeating_timer_callback(struct repeating_timer *t);
void do_dhcp(void);

int main()
{
    
    struct repeating_timer timer;
    stdio_init_all();
    sleep_ms(5000);
    printf("W5500 network install example.\r\n");

    wizchip_initialize();
    
    add_repeating_timer_ms(1000, repeating_timer_callback, NULL, &timer);
    setSHAR(net_info.mac);
    if (net_info.dhcp == NETINFO_DHCP)
    {

        dhcp_init();
    }
    else
    {
        wizchip_setnetinfo(&net_info);
        print_network_information(net_info);
    }
    while (true)
    {
        do_dhcp();
        sleep_ms(1000);
    }
}

static void dhcp_init(void)
{
    printf(" DHCP client running \r\n");
    DHCP_init(SOCKET_DHCP, ethernet_buf);
    reg_dhcp_cbfunc(dhcp_assign, dhcp_assign, dhcp_conflict);
}

static void dhcp_conflict(void)
{
    printf("CONFLICT IP from DHCP\r\n");
    while (1)
        ;
}

static void dhcp_assign(void)
{
    getIPfromDHCP(net_info.ip);
    getGWfromDHCP(net_info.gw);
    getSNfromDHCP(net_info.sn);
    getDNSfromDHCP(net_info.dns);

    net_info.dhcp = NETINFO_DHCP;

    wizchip_setnetinfo(&net_info);
    print_network_information(net_info);
    printf("DHCP LEASED TIME:%ld Sec.\r\n", getDHCPLeasetime());
}

bool repeating_timer_callback(struct repeating_timer *t)
{
    DHCP_time_handler();
    return true;
}

void do_dhcp(void)
{
    if (net_info.dhcp == NETINFO_DHCP)
    {
        retval = DHCP_run();
        if (retval == DHCP_IP_LEASED)
        {
            if (dhcp_get_ip_flag == 0)
            {
                printf("DHCP success\r\n");
                dhcp_get_ip_flag = 1;
            }
        }
        else if (retval == DHCP_FAILED)
        {
            dhcp_get_ip_flag = 0;
            dhcp_retry++;
            if (dhcp_retry <= DHCP_RETRY_COUNT)
            {
                printf(" DHCP timeout occurred and retry %d \r\n", dhcp_retry);
            }
        }

        if (dhcp_retry > DHCP_RETRY_COUNT)
        {
            printf(" DHCP failed \r\n");
            DHCP_stop();
            while (true)
                ;
        }
    }
}